package br.com.spam.pipeline.instruction.i;

import java.util.Map;

import br.com.spam.pipeline.core.ControlSignal;
import br.com.spam.pipeline.core.Processor;
import br.com.spam.pipeline.core.RegisterDataSource;
import br.com.spam.pipeline.instruction.ITypeInstruction;
import br.com.spam.pipeline.instruction.RsLoader;
import br.com.spam.pipeline.instruction.r.ADD;

public class ADDi extends ITypeInstruction
{

	public static final int ID = 1000;
	private final RsLoader loader;

	public ADDi(String instruction, Processor processor)
	{
		super(instruction, processor);
		this.loader = new RsLoader(this.rs(), this);
	}

	@Override
	public String getInstructionAsString()
	{
		return String.format("I%d: %s %s, %s, %d", this.index(), this.name(), this.rs().name(),
				this.rt().name(), this.immediate());
	}

	@Override
	protected boolean afterInstructionDecode()
	{
		return this.loader.instructionDecodeHook();
	}

	@Override
	public boolean execute()
	{
		this.loader.executionHook();
		this.rt()
				.write(this.loader.rsValue() + this.immediate(), RegisterDataSource.JustCalculated);
		return true;
	}

	@Override
	public final void generateControlSignals(Map<ControlSignal, Object> controlSignals)
	{
		controlSignals.put(ControlSignal.RegDst, 0);
		controlSignals.put(ControlSignal.ALUSrcB, 1);
		controlSignals.put(ControlSignal.MemToReg, 0);
		controlSignals.put(ControlSignal.RegWrite, 1);
		controlSignals.put(ControlSignal.MemWrite, 0);
		controlSignals.put(ControlSignal.Branch, 0);
		controlSignals.put(ControlSignal.Jump, 0);
		controlSignals.put(ControlSignal.ALUOp, ADD.ALUOpCode);
	}
}
